﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;
using XNAFormsLib;
using TimeQuest.Base;

namespace TimeQuest
{
    /// <summary>
    /// This is the main type for your game
    /// </summary>
    public class MainGame : XNAGame
    {
        #region Properties

        GameStates currentGameState = GameStates.Playing;
        SpriteBatch spriteBatch;
        XNAForm Menu;
        XNAForm MessageBox;
        string CurrentMessage = string.Empty;

        #region Static Properties

        public static Point ScreenResolution = new Point(640, 480);
        public static int DefaultFontID;
        public static int XNAFormID;
        public static int XNAMouseID;
        public static int InventoryItemTextureID;
        public static GameWorld theWorld;
        public static Player thePlayer;

        #endregion

        #endregion

        #region Constructor

        public MainGame()
        {
            Content.RootDirectory = "Content";
#if !DEBUG
            graphics.IsFullScreen = true;
            GameWorld.ShowBlockingRectangles = false;
#else
            GameWorld.ShowBlockingRectangles = true;
#endif
        }

        #endregion

        #region Events

        protected override void Initialize()
        {
            graphics.PreferredBackBufferWidth = ScreenResolution.X;
            graphics.PreferredBackBufferHeight = ScreenResolution.Y;
            graphics.ApplyChanges();

            ShowMouse = false;
            base.Initialize();

            Menu = new XNAForm(this);
            Menu.Location = new Point(0, 0);
            Menu.Width = Window.ClientBounds.Width;
            Menu.Height = 100;

            XNAButton Look = new XNAButton(this);
            Look.Location = new Point(6, 6);
            Look.Width =
                Look.Height = 88;
            Look.Text = "Look";
            Look.MouseDown += new EventHandler<MouseEventArgs>(Look_MouseDown);

            XNAButton Walk = new XNAButton(this);
            Walk.Location = new Point(94, 6);
            Walk.Width =
                Walk.Height = 88;
            Walk.Text = "Walk";
            Walk.MouseDown += new EventHandler<MouseEventArgs>(Walk_MouseDown);

            XNAButton Talk = new XNAButton(this);
            Talk.Location = new Point(6 + 2 * 88, 6);
            Talk.Width =
                Talk.Height = 88;
            Talk.Text = "Talk";
            Talk.MouseDown += new EventHandler<MouseEventArgs>(Talk_MouseDown);

            XNAButton Smell = new XNAButton(this);
            Smell.Location = new Point(6 + 3 * 88, 6);
            Smell.Width =
                Smell.Height = 88;
            Smell.Text = "Smell";
            Smell.MouseDown += new EventHandler<MouseEventArgs>(Smell_MouseDown);

            XNAButton Touch = new XNAButton(this);
            Touch.Location = new Point(6 + 4 * 88, 6);
            Touch.Width =
                Touch.Height = 88;
            Touch.Text = "Touch";
            Touch.MouseDown += new EventHandler<MouseEventArgs>(Touch_MouseDown);

            XNAButton Inventory = new XNAButton(this);
            Inventory.Location = new Point(6 + 5 * 88, 6);
            Inventory.Width = 100;
            Inventory.Height = 88;
            Inventory.Text = "Inventory";
            Inventory.MouseDown += new EventHandler<MouseEventArgs>(Inventory_MouseDown);

            XNAButton ShowBlock = new XNAButton(this);
            ShowBlock.Location = new Point(6 + 6 * 88, 6);
            ShowBlock.Width = 100;
            ShowBlock.Height = 88;
            ShowBlock.Text = "ShowBlock";
            ShowBlock.MouseDown += new EventHandler<MouseEventArgs>(ShowBlock_MouseDown);

            Menu.Controls.Add(Inventory);
            Menu.Controls.Add(ShowBlock);
            Menu.Controls.Add(Look);
            Menu.Controls.Add(Walk);
            Menu.Controls.Add(Talk);
            Menu.Controls.Add(Smell);
            Menu.Controls.Add(Touch);
            Forms.Add(Menu);

            MessageBox = new XNAForm(this);
            MessageBox.FormBorderStyle = FormBorderStyle.None;
            MessageBox.Visible = false;

            XNALabel lbl = new XNALabel(this);
            lbl.Location = new Point(0, 0);
            MessageBox.Controls.Add(lbl);

            Forms.Add(MessageBox);

        }

        void Inventory_MouseDown(object sender, MouseEventArgs e)
        {
            var inv = Forms.Where(x => x.Text == "Inventory").SingleOrDefault();
            if (inv != null)
                Forms.Remove(inv);

            XNAForm inventory = new XNAForm(this);
            inventory.Text = "Inventory";
            inventory.Center();
            inventory.Show();
            thePlayer.FillInventory(inventory);
            Forms.Add(inventory);
        }
        void ShowBlock_MouseDown(object sender, MouseEventArgs e)
        {
            GameWorld.ShowBlockingRectangles = !GameWorld.ShowBlockingRectangles;
        }
        void Touch_MouseDown(object sender, MouseEventArgs e)
        {
            InputHandler.SetCursor(Cursors.Touch);
        }
        void Smell_MouseDown(object sender, MouseEventArgs e)
        {
            InputHandler.SetCursor(Cursors.Smell);
        }
        void Talk_MouseDown(object sender, MouseEventArgs e)
        {
            InputHandler.SetCursor(Cursors.Talk);
        }
        void Walk_MouseDown(object sender, MouseEventArgs e)
        {
            InputHandler.SetCursor(Cursors.Walk);
        }
        void Look_MouseDown(object sender, MouseEventArgs e)
        {
            InputHandler.SetCursor(Cursors.Look);
        }

        #endregion

        protected override void LoadContent()
        {
            // Create a new SpriteBatch, which can be used to draw textures.
            spriteBatch = new SpriteBatch(GraphicsDevice);

            #region Load Textures

            XNAFormID = ContentHandler.AddTexture(Content.Load<Texture2D>("textures/xnaform"));
            InputHandler.MouseTextureID = ContentHandler.AddTexture(Content.Load<Texture2D>("Textures/Cursors"));
            XNAMouseID = ContentHandler.AddTexture(Content.Load<Texture2D>("textures/xnacursors"));
            InventoryItemTextureID = ContentHandler.AddTexture(Content.Load<Texture2D>("textures/inventoryitems"));
            int goid = ContentHandler.AddTexture(Content.Load<Texture2D>("textures/gameobjecttextures"));
            int questTestid = ContentHandler.AddTexture(Content.Load<Texture2D>("textures/QuestBG_1"));

            #endregion

            #region Load Fonts

            DefaultFontID = ContentHandler.AddFont(Content.Load<SpriteFont>("Fonts/font1"));
            DefaultFont = ContentHandler.GetFont(DefaultFontID);

            #endregion

            #region Load Player/World

            theWorld = CreateGame.QuestTest.CreateQuestTestGame(questTestid, goid);

            int playerid = ContentHandler.AddTexture(Content.Load<Texture2D>("textures/guy"));
            thePlayer = new Player(theWorld);
            thePlayer.Location = new Point(300, 200);
            thePlayer.GameObjectTextureID = playerid;


            theWorld.Player = thePlayer;

            #endregion

            SetDefaultTexture(ContentHandler.GetTexture(XNAFormID));
        }

        protected override void Update(GameTime gameTime)
        {
            #region GetStates
            MouseState ms = Mouse.GetState();
            KeyboardState ks = Keyboard.GetState();
            #endregion

            switch (currentGameState)
            {
                case GameStates.MainMenu:
                    break;
                case GameStates.Playing:
                    if (InputHandler.RightClicked(ms))
                        InputHandler.AdvanceCursor();

                    if (InputHandler.LeftClicked(ms) &&
                        InputHandler.CurrentCursor == Cursors.Walk)
                    {
                        thePlayer.WalkingTo = new Point(ms.X, ms.Y);
                        thePlayer.Moving = true;
                    }
                    if (InputHandler.CurrentCursor == Cursors.Look &&
                        InputHandler.LeftClicked(ms))
                    {
                        CurrentMessage = theWorld.CurrentScreen.ScreenDescription;
                        if (!string.IsNullOrEmpty(CurrentMessage))
                            currentGameState = GameStates.ShowingMessage;
                    }
                    if (InputHandler.CurrentCursor == Cursors.Touch &&
                        InputHandler.LeftClicked(ms))
                    {
                        var go = theWorld.CurrentScreen.GameObjects.Where(x => x.BaseRectangle.Within(new Point(ms.X, ms.Y)));
                        if (go.Count() > 0)
                        {
                            GameObject o = go.First();
                            o.Update(gameTime);
                        }
                    }

                    thePlayer.KeyPress(InputHandler.JustPressedList(ks));
                    thePlayer.Update(theWorld.CurrentScreen, gameTime);
                    break;
                case GameStates.ShowingMessage:
                    if (InputHandler.LeftClicked(ms))
                        currentGameState = GameStates.Playing;
                    break;
                default:
                    break;
            }

            #region Exit/Menu Stuff

            if (InputHandler.JustPressed(ks, Keys.Escape))
                this.Exit();
            if (ms.Y > 100)
                Menu.Visible = false;
            if (ms.Y < 10)
                Menu.Visible = true;

            #endregion

            #region Update InputHandler

            InputHandler.LastMouseState = ms;
            InputHandler.LastKeyboardState = ks;

            #endregion

            base.Update(gameTime);
        }

        protected override void Draw(GameTime gameTime)
        {
            #region Pre-Form Draw

            spriteBatch.Begin();
            theWorld.Draw(spriteBatch);
            spriteBatch.Draw(ContentHandler.GetTexture(XNAFormID),
                new Rectangle(0, 0, Window.ClientBounds.Width, 10),
                new Rectangle(2, 2, 0, 0),
                Color.White);

            spriteBatch.End();

            #endregion

            base.Draw(gameTime);

            #region Post-Form Draw

            spriteBatch.Begin();

            InputHandler.DrawMouse(spriteBatch, Mouse.GetState(), 1f, new Rectangle(0, 0, 25, 25));
            //spriteBatch.DrawString(FontHandler.GetFont(DefaultFontID), MouseHandler.CurrentCursor.ToString(), Vector2.Zero, Color.Black);

            //spriteBatch.DrawString(DefaultFont, "X: "+Mouse.GetState().X + "Y: " + Mouse.GetState().Y, Vector2.Zero, Color.White);
            spriteBatch.End();

            #endregion
        }
    }
}
